﻿namespace WebChat.Services.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Http;
    using WebChat.Data;
    using WebChat.Repositories;
    using WebChat.Models;
    using WebChat.Services.Models;
    using System.Net.Http;
    using System.Net;

    
    public class UserController : ApiController
    {
        private UserRepository data;

        public UserController()
        {
            this.data = new UserRepository(new WebChatContext());            
        }
        
        [HttpGet]
        public IEnumerable<UserModel> Get()
        {
            try
            {
                var allUsers = this.data.All().Select(UserModel.FromUser());
                return allUsers;
            }
            catch (Exception ex)
            {
                var response = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
                throw new HttpResponseException(response);
            }
            
        }       
                   
        public UserModel Get(int id)
        {
            return this.PerformOperationAndHandleExceptions(() =>
            {
                var user = this.data.Get(id);
                if (user == null)
                {
                    throw new Exception("User not found");                    
                }

                UserModel model = new UserModel
                {
                    UserId = user.UserId,
                    Username = user.Username,
                    PictureUrl = user.PictureUrl
                };
                return model;
            });
        }
        
        [HttpPost]
        [ActionName("register")]
        public HttpResponseMessage RegisterUser([FromBody]UserRegisterModel registerModel)
        {
            return this.PerformOperationAndHandleExceptions(() =>
            {             
                var user = data.Add(registerModel.ToUser());
                string sessionKey = this.data.Login(user);
                var logged = new UserLoggedModel
                {
                      Username = user.Username,
                      SessionKey = sessionKey
                };

                var response = this.Request.CreateResponse(HttpStatusCode.Created, logged);
                return response;
            });
        }
        
        [HttpPost]
        [ActionName("login")]
        public HttpResponseMessage LoginUser(UserRegisterModel registerModel)
        {
            return this.PerformOperationAndHandleExceptions(() =>
            {
                var user = registerModel.ToUser();
                string sessionKey = this.data.Login(user);
                var logged = new UserLoggedModel
                {
                    Username = user.Username,
                    SessionKey = sessionKey
                };

                var response = this.Request.CreateResponse(HttpStatusCode.Created, logged);
                return response;
            });
        }

        [HttpGet]
        [ActionName("logout")]
        public HttpResponseMessage LogoutUser(string sessionKey)
        {
            return this.PerformOperationAndHandleExceptions(() =>
            {
                this.data.Logout(sessionKey);
                var response = this.Request.CreateResponse(HttpStatusCode.OK);
                return response;
            });
        }

        protected T PerformOperationAndHandleExceptions<T>(Func<T> action)
        {
            try
            {
               return action();
            }
            catch (Exception ex)
            {
                var response = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
                throw new HttpResponseException(response);
            }
        }
    }
}
